home *** CD-ROM | disk | FTP | other *** search
-
- /****************************************************************************
-
- X6502.C
-
- - heap initializer, opcode routines, entry and exit routines
-
- 01/23/88 created
- 03/03/88 Laser C
-
- 07/08/88 21:00
-
- ****************************************************************************/
-
- #include <stdio.h>
- #include <osbind.h>
- #include "xglobal.h"
- #include "x6502.h"
-
- /* format of mnemonics: 3 ascii codes of the opcode and the addressing mode:
- 00 - implied 01 - immediate 02 - zero page 03 - zero page,x
- 04 - zero page,y 05 - (zero page,x) 06 - (zero page),y
- 07 - absolute 08 - absolute,x 09 - absolute,y 0A - accumulator
- 0B - relative 0C - indirect 0D - absolute indirect
-
- used by the 6502 monitor for disassembling code
- */
-
- long rglMnemonics[256] =
- {
- 0x42524B00L, 0x4F524105L, 0x3F3F3F00L, 0x3F3F3F00L, 0x3F3F3F00L, 0x4F524102L,
- 0x41534C02L, 0x3F3F3F00L, 0x50485000L, 0x4F524101L, 0x41534C0AL, 0x3F3F3F00L,
- 0x3F3F3F00L, 0x4F524107L, 0x41534C07L, 0x3F3F3F00L, 0x42504C0BL, 0x4F524106L,
- 0x3F3F3F00L, 0x3F3F3F00L, 0x3F3F3F00L, 0x4F524103L, 0x41534C03L, 0x3F3F3F00L,
- 0x434C4300L, 0x4F524109L, 0x3F3F3F00L, 0x3F3F3F00L, 0x3F3F3F00L, 0x4F524108L,
- 0x41534C08L, 0x3F3F3F00L, 0x4A535207L, 0x414E4405L, 0x3F3F3F00L, 0x3F3F3F00L,
- 0x42495402L, 0x414E4402L, 0x524F4C02L, 0x3F3F3F00L, 0x504C5000L, 0x414E4401L,
- 0x524F4C0AL, 0x3F3F3F00L, 0x42495407L, 0x414E4407L, 0x524F4C07L, 0x3F3F3F00L,
- 0x424D490BL, 0x414E4406L, 0x3F3F3F00L, 0x3F3F3F00L, 0x3F3F3F00L, 0x414E4403L,
- 0x524F4C03L, 0x3F3F3F00L, 0x53454300L, 0x414E4409L, 0x3F3F3F00L, 0x3F3F3F00L,
- 0x3F3F3F00L, 0x414E4408L, 0x524F4C08L, 0x3F3F3F00L, 0x52544900L, 0x454F5205L,
- 0x4C53520AL, 0x3F3F3F00L, 0x4A4D5007L, 0x454F5202L, 0x4C535202L, 0x3F3F3F00L,
- 0x50484100L, 0x454F5201L, 0x4C53520AL, 0x3F3F3F00L, 0x4A4D5007L, 0x454F5207L,
- 0x4C535207L, 0x3F3F3F00L, 0x4256430BL, 0x454F5206L, 0x3F3F3F00L, 0x3F3F3F00L,
- 0x3F3F3F00L, 0x454F5203L, 0x4C535203L, 0x3F3F3F00L, 0x434C4900L, 0x454F5209L,
- 0x3F3F3F00L, 0x3F3F3F00L, 0x3F3F3F00L, 0x454F5208L, 0x4C535208L, 0x3F3F3F00L,
- 0x52545300L, 0x41444305L, 0x3F3F3F00L, 0x3F3F3F00L, 0x3F3F3F00L, 0x41444302L,
- 0x524F5202L, 0x3F3F3F00L, 0x504C4100L, 0x41444301L, 0x524F520AL, 0x3F3F3F00L,
- 0x4A4D500CL, 0x41444307L, 0x524F5207L, 0x3F3F3F00L, 0x4256530BL, 0x41444306L,
- 0x3F3F3F00L, 0x3F3F3F00L, 0x3F3F3F00L, 0x41444303L, 0x524F5203L, 0x3F3F3F00L,
- 0x53454900L, 0x41444309L, 0x3F3F3F00L, 0x3F3F3F00L, 0x3F3F3F00L, 0x41444308L,
- 0x524F5208L, 0x3F3F3F00L, 0X3F3F3F00L, 0X53544105L, 0X3F3F3F00L, 0X3F3F3F00L,
- 0X53545902L, 0X53544102L, 0X53545802L, 0X3F3F3F00L, 0X44455900L, 0X3F3F3F00L,
- 0X54584100L, 0X3F3F3F00L, 0X53545907L, 0X53544107L, 0X53545807L, 0X3F3F3F00L,
- 0X4243430BL, 0X53544106L, 0X3F3F3F00L, 0X3F3F3F00L, 0X53545903L, 0X53544103L,
- 0X53545804L, 0X3F3F3F00L, 0X54594100L, 0X53544109L, 0X54585300L, 0X3F3F3F00L,
- 0X3F3F3F00L, 0X53544108L, 0X3F3F3F00L, 0X3F3F3F00L, 0X4C445901L, 0X4C444105L,
- 0X4C445801L, 0X3F3F3F00L, 0X4C445902L, 0X4C444102L, 0X4C445802L, 0X3F3F3F00L,
- 0X54415900L, 0X4C444101L, 0X54415800L, 0X3F3F3F00L, 0X4C445907L, 0X4C444107L,
- 0X4C445807L, 0X3F3F3F00L, 0X4243530BL, 0X4C444106L, 0X3F3F3F00L, 0X3F3F3F00L,
- 0X4C445903L, 0X4C444103L, 0X4C445804L, 0X3F3F3F00L, 0X434C5600L, 0X4C444109L,
- 0X54535800L, 0X3F3F3F00L, 0X4C445908L, 0X4C444108L, 0X4C445809L, 0X3F3F3F00L,
- 0X43505901L, 0X434D5005L, 0X3F3F3F00L, 0X3F3F3F00L, 0X43505902L, 0X434d5002L,
- 0X44454302L, 0X3F3F3F00L, 0X494E5900L, 0X434D5001L, 0X44455800L, 0X3F3F3F00L,
- 0X43505907L, 0X434D5007L, 0X44454307L, 0X3F3F3F00L, 0X424E450BL, 0X434D5006L,
- 0X3F3F3F00L, 0X3F3F3F00L, 0X3F3F3F00L, 0X434D5003L, 0X44454303L, 0X3F3F3F00L,
- 0X434C4400L, 0X434D5009L, 0X3F3F3F00L, 0X3F3F3F00L, 0X3F3F3F00L, 0X434D5008L,
- 0X44454308L, 0X3F3F3F00L, 0X43505801L, 0X53424305L, 0X3F3F3F00L, 0X3F3F3F00L,
- 0X43505802L, 0X53424302L, 0X494E4302L, 0X3F3F3F00L, 0X494E5800L, 0X53424301L,
- 0X4E4F5000L, 0X3F3F3F00L, 0X43505807L, 0X53424307L, 0X494E4307L, 0X3F3F3F00L,
- 0X4245510BL, 0X53424306L, 0X3F3F3F00L, 0X3F3F3F00L, 0X3F3F3F00L, 0X53424303L,
- 0X494E4303L, 0X3F3F3F00L, 0X53454400L, 0X53424309L, 0X3F3F3F00L, 0X3F3F3F00L,
- 0X3F3F3F00L, 0X53424308L, 0X494E4308L, 0X3F3F3F00L
- } ;
-
- /* create an array of pointers to 256 functions */
- int (*vec_6502[257])() =
- {
- op00, op01, op02, op03, op04, op05, op06, op07, op08, op09, op0A, op0B,
- op0C, op0D, op0E, op0F, op10, op11, op12, op13, op14, op15, op16, op17,
- op18, op19, op1A, op1B, op1C, op1D, op1E, op1F, op20, op21, op22, op23,
- op24, op25, op26, op27, op28, op29, op2A, op2B, op2C, op2D, op2E, op2F,
- op30, op31, op32, op33, op34, op35, op36, op37, op38, op39, op3A, op3B,
- op3C, op3D, op3E, op3F, op40, op41, op42, op43, op44, op45, op46, op47,
- op48, op49, op4A, op4B, op4C, op4D, op4E, op4F, op50, op51, op52, op53,
- op54, op55, op56, op57, op58, op59, op5A, op5B, op5C, op5D, op5E, op5F,
- op60, op61, op62, op63, op64, op65, op66, op67, op68, op69, op6A, op6B,
- op6C, op6D, op6E, op6F, op70, op71, op72, op73, op74, op75, op76, op77,
- op78, op79, op7A, op7B, op7C, op7D, op7E, op7F, op80, op81, op82, op83,
- op84, op85, op86, op87, op88, op89, op8A, op8B, op8C, op8D, op8E, op8F,
- op90, op91, op92, op93, op94, op95, op96, op97, op98, op99, op9A, op9B,
- op9C, op9D, op9E, op9F, opA0, opA1, opA2, opA3, opA4, opA5, opA6, opA7,
- opA8, opA9, opAA, opAB, opAC, opAD, opAE, opAF, opB0, opB1, opB2, opB3,
- opB4, opB5, opB6, opB7, opB8, opB9, opBA, opBB, opBC, opBD, opBE, opBF,
- opC0, opC1, opC2, opC3, opC4, opC5, opC6, opC7, opC8, opC9, opCA, opCB,
- opCC, opCD, opCE, opCF, opD0, opD1, opD2, opD3, opD4, opD5, opD6, opD7,
- opD8, opD9, opDA, opDB, opDC, opDD, opDE, opDF, opE0, opE1, opE2, opE3,
- opE4, opE5, opE6, opE7, opE8, opE9, opEA, opEB, opEC, opED, opEE, opEF,
- opF0, opF1, opF2, opF3, opF4, opF5, opF6, opF7, opF8, opF9, opFA, opFB,
- opFC, opFD, opFE, opFF, opXX
- };
-
- void init_heap()
- {
- register long lToHeap;
- int iHeap=0;
- register int opcode = 0;
- register long lOpcode, lNextOp;
-
- #ifdef NDEBUG
- printf("vec_6502 = %6lx\nlEmul = %6lx\n", vec_6502, lEmul);
- #endif
-
- /* first blit the 256 opcodes */
- do
- {
- lToHeap = lEmul + iHeap + cbDISPATCH;
- lOpcode = (long)vec_6502[opcode];
- lNextOp = (long)vec_6502[opcode+1];
- #ifdef NDEBUG
- printf("Blit %d bytes, opcode %2x, from %6lx to %6lx\n",
- (int)(lNextOp - lOpcode), opcode, lOpcode, lToHeap);
- #endif
- Blitb(lOpcode, lToHeap,
- (int)(lNextOp - lOpcode));
-
- Assert(((int)(lNextOp - lOpcode)) >= 0, "blitting negative");
- Assert(((int)(lNextOp - lOpcode)) != 0, "blitting 0");
- Assert(((int)(lNextOp - lOpcode)) < 122, "blitting >122");
-
- iHeap += 256;
- opcode++;
- } while (iHeap != 0);
-
- /* then blit the dispatcher and interpreter globals */
- #ifdef NDEBUG
- printf("\nBlit %d bytes of globals from %6lx to %6lx\n",
- cbGLOBALS, Lglobals, lEmul - cbGLOBALS);
- #endif
- Blitb(Lglobals, lEmul - cbGLOBALS, cbGLOBALS);
- #ifdef NDEBUG
- printf("Blit %d bytes of dispatcher from %6lx to %6lx\n",
- cbDISPATCH, Lemul, lEmul);
- #endif
- Blitb(Lemul, lEmul, cbDISPATCH);
-
- /* now fill in important globals */
- asm
- {
- ; set up interrupt vector
- move.l lEmul,A0
- lea lInterrupt(A0),A0
- move.w #OP_JMP,(A0)
- }
- }
-
- /********************************************************************
- **
- ** This is the main entry point into the interpreter.
- ** At entry, all 6502 registers must already be properly initialized.
- ** This routine must be called in supervisor mode.
- **
- ********************************************************************/
-
- execute()
- {
-
- if (!fTrace)
- {
- #ifdef DEBUG
- Setscreen(lScr+3840L, lScr+3840L, -1);
- #else
- Setscreen(-1L, lScr+3840L, -1);
- #endif
- if (!fIsMono)
- *(char *)0xFFFF8260L = 0;
-
- (*pHookIn)();
- }
-
- #ifdef NDEBUG
- printf("execute(): hooked in!\n");
- #endif
-
- asm {
-
- ; copy important registers into interpreter's area
- move.l lEmul,arEMUL
-
- ; restore both instruction words of dispatcher
- move.l Lemul,(arEMUL)
-
- ; patch up the dispatcher if trace is on
- tst.w fTrace
- beq.s notrace ; if trace bit set...
- move.w #OP_RTS,(arEMUL) ; make dispatcher RTS after 1 opcode
- notrace:
-
- ; fill in remaining interpreter registers
- lea 4(arEMUL),arEMVEC
- move.l lMemory,drEA
- move.l drEA,drSP ; set high word
- move.l drEA,drEA ; set high word
- move.l drEA,drA ; ditto
- move.l drEA,drX ; ditto
- move.l drEA,drY ; ditto
- ; move.l drEA,drST ; ditto
- move.l lRStat,arRSTAT
- move.l lWStat,arWSTAT
-
- ; convert P register to drST etc...
- P_to_ST
-
- ; load remaining 6502 registers
- move.b bRegA(arEMUL),drA
- move.b bRegX(arEMUL),drX
- move.b bRegY(arEMUL),drY
- move.w wRegPC(arEMUL),drEA
- move.l drEA,arPC
-
- ; stack is on page 1
- move.b #0x01,wRegSP(arEMUL)
- move.w wRegSP(arEMUL),drSP
-
- ; clear all interrupts
- clr.b bNMI(arEMUL)
- clr.b bIRQ(arEMUL)
-
- ; the dispatch routine is not called directly, in case we patched
- ; an RTS into it. So execute the first instruction from here
- move.b (arPC)+,(arEMVEC)
- jsr 2(arEMUL) ; go emulate!!
-
- move.b drA,bRegA(arEMUL) ; save 6502 registers
- move.b drX,bRegX(arEMUL)
- move.b drY,bRegY(arEMUL)
- move.w drSP,wRegSP(arEMUL)
- move.w arPC,wRegPC(arEMUL)
- move.w arEA,wEA(arEMUL)
-
- ST_to_P
- }
-
- if (!fTrace)
- {
- #ifdef DEBUG
- Setscreen(lScrGEM, lScrGEM, -1);
- #else
- Setscreen(-1L, lScrGEM, -1);
- #endif
- if (!fIsMono)
- *(char *)0xFFFF8260L = 1;
-
- (*pUnHook)();
- }
- }
-
-
- /* this function contains all of the 6502 related code
- ** that will be relocated to the heap.
- */
-
- pcode()
- {
- asm {
-
- ; The bytes immediately preceeding the dispatch routine are used as
- ; the global variable area for the interpreter and service routines,
- ; and is the link through which we communicate to the monitor.
- ; This must be blitted as a whole to the heap.
- ; Offsets in _X6502.H must match up with the declarations here.
-
- Lglobals:
- dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 16 jump vectors
- dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; save space for D0-D7,A0-A5
- dc.b 0 ; NMI interrupt bits
- dc.b 0 ; IRQ interrupt bits
- dc.b 0 ; IRQ enable mask
- dc.b 0 ; bB
- dc.b 0 ; bD
- dc.b 0 ; bI
- dc.b 0 ; bV
- dc.b 0 ; bCX
- dc.b 0 ; bRegA
- dc.b 0 ; bRegX
- dc.b 0 ; bRegY
- dc.b 0 ; bRegP
- dc.w 0 ; wRegSP
- dc.w 0 ; wRegPC
- dc.w 0 ; wEA
- dc.w 0 ; wExitCode
-
- LInterrupt:
- dc.w 0 ; jmp
- LIntVec:
- dc.l 0 ; NMI and IRQ routine
-
- LWriteDisp:
- move.b drDATA,-10(arEMUL)
- jmp iWrite(arEMUL)
-
- LReadDisp:
- move.b drDATA,-2(arEMUL)
- jmp iRead(arEMUL)
-
- Lemul:
- move.b (arPC)+,(arEMVEC)
- jmp 2(PC)
-
- ; BRK
- op00:
- UNUSED
- ; st bB(arEMUL)
- ; move.w #EXIT_BREAK,wExitCode(arEMUL)
- ; rts
-
- ; ORA (zp,X)
- op01:
- EA_zpXind
- ReadService
- or.b (arEA),drA ; ORA with accumualtor
- move.b drA,drST
- ext.w drST
- DISPATCH ; and go do another opcode
-
- op02:
- UNUSED
- op03:
- UNUSED
- op04:
- UNUSED
-
- ; ORA zp
- op05:
- EA_zp
- or.b (arEA),drA ; ORA with accumualtor
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; ASL zp
- op06:
- EA_zp
- move.b (arEA),drST ; must do in register as memory shifts word
- add.b drST,drST
- scs drC
- ext.w drST
- move.b drST,(arEA)
- DISPATCH
-
- op07:
- UNUSED
-
- ; PHP - do a 68000 to 6502 flag conversion, like in the init code
- op08:
- ST_to_P
- move.l drSP,arEA
- move.b bRegP(arEMUL),(arEA)
- subq.b #1,drSP
- DISPATCH
-
- ; ORA #
- op09:
- or.b (arPC)+,drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; ASL A
- op0A:
- add.b drA,drA
- scs drC
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- op0B:
- UNUSED
- op0C:
- UNUSED
-
- ; ORA abs
- op0D:
- EA_abs
- ReadService
- or.b (arEA),drA ; ORA with accumualtor
- move.b drA,drST
- ext.w drST
- DISPATCH ; and go do another opcode
-
- ; ASL abs
- op0E:
- EA_abs
- ReadService
- move.b (arEA),drST ; must do in register as memory shifts word
- add.b drST,drST
- scs drC
- ext.w drST
- move.b drST,(arEA)
- DISPATCH
-
- op0F:
- UNUSED
-
- ; BPL
- op10:
- move.b (arPC)+,drDATA
- tst.w drST
- bmi.s nobpl
- ext.w drDATA
- adda.w drDATA,arPC
- nobpl:
- DISPATCH
-
- ; ORA (zp),Y
- op11:
- EA_zpYind
- ReadService
- or.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- op12:
- UNUSED
- op13:
- UNUSED
- op14:
- UNUSED
-
- ; ORA zp,X
- op15:
- EA_zpX
- or.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; ASL zp,X
- op16:
- EA_zpX
- move.b (arEA),drST ; must do in register as memory shifts word
- add.b drST,drST
- scs drC
- ext.w drST
- move.b drST,(arEA)
- DISPATCH
-
- op17:
- UNUSED
-
- ; CLC
- op18:
- clr.b drC
- DISPATCH
-
- ; ORA abs,Y
- op19:
- EA_absY
- ReadService
- or.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- op1A:
- UNUSED
- op1B:
- UNUSED
- op1C:
- UNUSED
-
- ; ORA abs,X
- op1D:
- EA_absX
- ReadService
- or.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; ASL abs,X
- op1E:
- EA_absX
- ReadService
- move.b (arEA),drST ; must do in register as memory shifts word
- add.b drST,drST
- scs drC
- ext.w drST
- move.b drST,(arEA)
- DISPATCH
-
- op1F:
- UNUSED
-
- ; JSR abs
- op20:
- subq.b #2,drSP
- move.l drSP,arEA
- move.w arPC,drEA
- addq.w #1,drEA
- move.b drEA,1(arEA) ; push PClo
- move.w drEA,-(SP)
- move.b (SP)+,2(arEA) ; push PChi
- dc.w 0x0F09,0x0001 ; movep.w 1(arPC),drEA
- move.b (arPC),drEA
- move.l drEA,arPC
- DISPATCH
-
- ; AND (zp,X)
- op21:
- EA_zpXind
- ReadService
- and.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- op22:
- UNUSED
- op23:
- UNUSED
-
- ; BIT zp
- op24:
- EA_zp
- move.b (arEA),drST
- ext.w drST
- ; tst.b drDATA ; V bit not set by a tst
- btst #6,drST
- sne bV(arEMUL) ; V bit
- and.b drA,drST ; NZ bits
- DISPATCH
-
- ; AND zp
- op25:
- EA_zp
- and.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; ROL zp
- op26:
- EA_zp
- move.b (arEA),drST ; get byte
- add.b drC,drC
- addx.b drST,drST ; shift it
- scs drC
- ext.w drST
- move.b drST,(arEA) ; save in memory
- DISPATCH
-
- op27:
- UNUSED
-
- ; PLP
- op28:
- addq.b #1,drSP
- move.l drSP,arEA
- move.b (arEA),bRegP(arEMUL)
- P_to_ST
- DISPATCH
-
- ; AND #
- op29:
- and.b (arPC)+,drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; ROL A
- op2A:
- add.b drC,drC
- addx.b drA,drA
- scs drC
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- op2B:
- UNUSED
-
- ; BIT abs
- op2C:
- EA_abs
- ReadService
- move.b (arEA),drST
- ext.w drST
- ; tst.b drDATA ; V bit not set by a tst
- btst #6,drST
- sne bV(arEMUL) ; V bit
- and.b drA,drST ; NZ bits
- DISPATCH
-
- ; AND abs
- op2D:
- EA_abs
- ReadService
- and.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; ROL abs
- op2E:
- EA_abs
- ReadService
- move.b (arEA),drST ; get byte
- add.b drC,drC
- addx.b drST,drST ; shift it
- scs drC
- ext.w drST
- move.b drST,(arEA) ; save in memory
- DISPATCH
-
- op2F:
- UNUSED
-
- ; BMI
- op30:
- move.b (arPC)+,drDATA
- tst.w drST
- bpl.s nobmi
- ext.w drDATA
- adda.w drDATA,arPC
- nobmi:
- DISPATCH
-
- ; AND (zp),Y
- op31:
- EA_zpYind
- ReadService
- and.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- op32:
- UNUSED
- op33:
- UNUSED
- op34:
- UNUSED
-
-
- ; AND zp,X
- op35:
- EA_zpX
- and.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; ROL zp,X
- op36:
- EA_zpX
- move.b (arEA),drST ; get byte
- add.b drC,drC
- addx.b drST,drST ; shift it
- scs drC
- ext.w drST
- move.b drST,(arEA) ; save in memory
- DISPATCH
-
- op37:
- UNUSED
-
- ; SEC
- op38:
- st drC
- DISPATCH
-
- ; AND abs,Y
- op39:
- EA_absY
- ReadService
- and.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- op3A:
- UNUSED
- op3B:
- UNUSED
- op3C:
- UNUSED
-
- ; AND abs,X
- op3D:
- EA_absX
- ReadService
- and.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; ROL abs,X
- op3E:
- EA_absX
- ReadService
- move.b (arEA),drST ; get byte
- add.b drC,drC
- addx.b drST,drST ; shift it
- scs drC
- ext.w drST
- move.b drST,(arEA) ; save in memory
- DISPATCH
-
- op3F:
- UNUSED
-
- ; RTI
- op40:
- move.l drSP,arEA
- move.b 3(arEA),-(SP) ; pull PChi
- move.w (SP)+,drEA
- move.b 2(arEA),drEA ; pull PClo
- move.l drEA,arPC ; do NOT increment PC for an RTI
- move.b 1(arEA),bRegP(arEMUL) ; pull processor
- P_to_ST
- addq.b #3,drSP
-
- tst.b bNMI(arEMUL) ; check if NMI pending
- bne op40_2
-
- tst.b bI(arEMUL)
- bne op40_x
-
- tst.b bIRQ(arEMUL) ; check if other interrupts pending
- beq op40_x
-
- op40_2:
- move.w #OP_INT,(arEMUL)
-
- op40_x:
- DISPATCH
-
- ; EOR (zp,X)
- op41:
- EA_zpXind
- ReadService
- move.b (arEA),drDATA
- eor.b drDATA,drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- op42:
- UNUSED
- op43:
- UNUSED
- op44:
- UNUSED
-
- ; EOR zp
- op45:
- EA_zp
- move.b (arEA),drDATA
- eor.b drDATA,drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; LSR zp
- op46:
- EA_zp
- move.b (arEA),drST
- lsr.b #1,drST
- scs drC
- ext.w drST
- move.b drST,(arEA)
- DISPATCH
-
- op47:
- UNUSED
-
- ; PHA
- op48:
- move.l drSP,arEA
- move.b drA,(arEA) ; push acc
- subq.b #1,drSP
- DISPATCH
-
- ; EOR #
- op49:
- move.b (arPC)+,drDATA
- eor.b drDATA,drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; LSR A
- op4A:
- lsr.b #1,drA
- scs drC
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- op4B:
- UNUSED
-
- ; JMP abs
- op4C:
- dc.w 0x0F09,0x0001 ; movep.w 1(arPC),drEA
- move.b (arPC),drEA
- move.l drEA,arPC
- DISPATCH
-
- ; EOR abs
- op4D:
- EA_abs
- ReadService
- move.b (arEA),drDATA
- eor.b drDATA,drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; LSR abs
- op4E:
- EA_abs
- ReadService
- move.b (arEA),drST
- lsr.b #1,drST
- scs drC
- ext.w drST
- move.b drST,(arEA)
- DISPATCH
-
- op4F:
- UNUSED
-
- ; BVC
- op50:
- move.b (arPC)+,drDATA
- tst.b bV(arEMUL)
- bne.s nobvc
- ext.w drDATA
- adda.w drDATA,arPC
- nobvc:
- DISPATCH
-
- ; EOR (zp),Y
- op51:
- EA_zpYind
- ReadService
- move.b (arEA),drDATA
- eor.b drDATA,drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- op52:
- UNUSED
- op53:
- UNUSED
- op54:
- UNUSED
-
- ; EOR zp,X
- op55:
- EA_zpX
- move.b (arEA),drDATA
- eor.b drDATA,drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; LSR zp,X
- op56:
- EA_zpX
- move.b (arEA),drST
- lsr.b #1,drST
- scs drC
- ext.w drST
- move.b drST,(arEA)
- DISPATCH
-
- op57:
- UNUSED
-
- ; CLI
- op58:
- sf bI(arEMUL)
-
- tst.b bIRQ(arEMUL) ; check if other interrupts pending
- beq op58_x
-
- move.w #OP_INT,(arEMUL)
-
- op58_x:
- DISPATCH
-
- ; EOR abs,Y
- op59:
- EA_absY
- ReadService
- move.b (arEA),drDATA
- eor.b drDATA,drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- op5A:
- UNUSED
- op5B:
- UNUSED
- op5C:
- UNUSED
-
- ; EOR abs,X
- op5D:
- EA_absX
- ReadService
- move.b (arEA),drDATA
- eor.b drDATA,drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; LSR abs,X
- op5E:
- EA_absX
- ReadService
- move.b (arEA),drST
- lsr.b #1,drST
- scs drC
- ext.w drST
- move.b drST,(arEA)
- DISPATCH
-
- op5F:
- UNUSED
-
- ; RTS
- op60:
- move.l drSP,arEA
- move.b 2(arEA),-(SP) ; pull PChi
- move.w (SP)+,drEA
- move.b 1(arEA),drEA ; pull PClo
- addq.b #2,drSP
- addq.w #1,drEA
- move.l drEA,arPC
- DISPATCH
-
- ; ADC (zp,X)
- op61:
- tst.l drST ; test D flag
- bmi.s op61dec
- EA_zpXind
- ReadService
- move.b (arEA),drDATA
- add.b drC,drC
- addx.b drDATA,drA
- scs drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
- op61dec:
- EA_zpXind
- ReadService
- move.b (arEA),drDATA
- add.b drC,drC ; set X flag
- clr.b drC ; sets Z flag for the ABCD without clearing X
- abcd drDATA,drA
- scs drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- op62:
- UNUSED
- op63:
- UNUSED
- op64:
- UNUSED
-
- ; ADC zp
- op65:
- tst.l drST ; test D flag
- ; tst.b bD(arEMUL)
- bmi.s op65dec
- EA_zp
- move.b (arEA),drDATA
- add.b drC,drC
- addx.b drDATA,drA
- scs drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
- op65dec:
- EA_zp
- move.b (arEA),drDATA
- add.b drC,drC ; set X flag
- clr.b drC ; sets Z flag for the ABCD without clearing X
- abcd drDATA,drA
- scs drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; ROR zp
- op66:
- EA_zp
- move.b (arEA),drST
- add.b drC,drC
- roxr.b #1,drST
- scs drC
- ext.w drST
- move.b drST,(arEA)
- DISPATCH
-
- op67:
- UNUSED
-
- ; PLA
- op68:
- addq.b #1,drSP
- move.l drSP,arEA
- move.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; ADC #
- op69:
- tst.l drST ; test D flag
- ; tst.b bD(arEMUL)
- bmi.s op69dec
- move.b (arPC)+,drDATA
- add.b drC,drC
- addx.b drDATA,drA
- scs drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
- op69dec:
- move.b (arPC)+,drDATA
- add.b drC,drC ; set X flag
- clr.b drC ; sets Z flag for the ABCD without clearing X
- abcd drDATA,drA
- scs drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; ROR A
- op6A:
- add.b drC,drC
- roxr.b #1,drA
- scs drC
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- op6B:
- UNUSED
-
- ; JMP (abs)
- op6C:
- EA_abs
- dc.w 0x0F08,0x0001 ; movep.w 1(arEA),drEA
- move.b (arEA),drEA
- move.l drEA,arPC
- DISPATCH
-
- ; ADC abs
- op6D:
- EA_abs
- ReadService
- tst.l drST ; test D flag
- ; tst.b bD(arEMUL)
- bmi.s op6Ddec
- move.b (arEA),drDATA
- add.b drC,drC
- addx.b drDATA,drA
- scs drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
- op6Ddec:
- move.b (arEA),drDATA
- add.b drC,drC ; set X flag
- clr.b drC ; sets Z flag for the ABCD without clearing X
- abcd drDATA,drA ; ADDX.B or ABCD drDATA,drA
- scs drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; ROR abs
- op6E:
- EA_abs
- ReadService
- add.b drC,drC
- move.b (arEA),drST
- roxr.b #1,drST
- scs drC
- ext.w drST
- move.b drST,(arEA)
- DISPATCH
-
- op6F:
- UNUSED
-
- ; BVS
- op70:
- move.b (arPC)+,drDATA
- tst.b bV(arEMUL)
- beq.s nobvs
- ext.w drDATA
- adda.w drDATA,arPC
- nobvs:
- DISPATCH
-
- ; ADC (zp),Y
- op71:
- EA_zpYind
- ReadService
- tst.l drST ; test D flag
- ; tst.b bD(arEMUL)
- bmi.s op71dec
- move.b (arEA),drDATA
- add.b drC,drC
- addx.b drDATA,drA
- scs drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
- op71dec:
- move.b (arEA),drDATA
- add.b drC,drC ; set X flag
- clr.b drC ; sets Z flag for the ABCD without clearing X
- abcd drDATA,drA
- scs drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- op72:
- UNUSED
- op73:
- UNUSED
- op74:
- UNUSED
-
- ; ADC zp,X
- op75:
- EA_zpX
- tst.l drST ; test D flag
- ; tst.b bD(arEMUL)
- bmi.s op75dec
- move.b (arEA),drDATA
- add.b drC,drC
- addx.b drDATA,drA
- scs drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
- op75dec:
- move.b (arEA),drDATA
- add.b drC,drC ; set X flag
- clr.b drC ; sets Z flag for the ABCD without clearing X
- abcd drDATA,drA
- scs drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; ROR zp,X
- op76:
- EA_zpX
- add.b drC,drC
- move.b (arEA),drST
- roxr.b #1,drST
- scs drC
- ext.w drST
- move.b drST,(arEA)
- DISPATCH
-
- op77:
- UNUSED
-
- ; SEI
- op78:
- st bI(arEMUL)
- DISPATCH
-
- ; ADC abs,Y
- op79:
- EA_absY
- ReadService
- tst.l drST ; test D flag
- ; tst.b bD(arEMUL)
- bmi.s op79dec
- move.b (arEA),drDATA
- add.b drC,drC
- addx.b drDATA,drA
- scs drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
- op79dec:
- move.b (arEA),drDATA
- add.b drC,drC ; set X flag
- clr.b drC ; sets Z flag for the ABCD without clearing X
- abcd drDATA,drA ; ADDX.B or ABCD drDATA,drA
- scs drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- op7A:
- UNUSED
- op7B:
- UNUSED
- op7C:
- UNUSED
-
- ; ADC abs,X
- op7D:
- EA_absX
- ReadService
- tst.l drST ; test D flag
- ; tst.b bD(arEMUL)
- bmi.s op7Ddec
- move.b (arEA),drDATA
- add.b drC,drC
- addx.b drDATA,drA
- scs drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
- op7Ddec:
- move.b (arEA),drDATA
- add.b drC,drC ; set X flag
- clr.b drC ; sets Z flag for the ABCD without clearing X
- abcd drDATA,drA
- scs drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; ROR abs,X
- op7E:
- EA_absX
- ReadService
- add.b drC,drC
- move.b (arEA),drST
- roxr.b #1,drST
- scs drC
- ext.w drST
- move.b drST,(arEA)
- DISPATCH
-
- op7F:
- UNUSED
- op80:
- UNUSED
-
- ; STA (zp,X)
- op81:
- EA_zpXind
- WriteAService
- move.b drA,(arEA)
- DISPATCH
-
- op82:
- UNUSED
- op83:
- UNUSED
-
- ; STY zp
- op84:
- EA_zp
- move.b drY,(arEA)
- DISPATCH
-
- ; STA zp
- op85:
- EA_zp
- move.b drA,(arEA)
- DISPATCH
-
- ; STX zp
- op86:
- EA_zp
- move.b drX,(arEA)
- DISPATCH
-
- op87:
- UNUSED
-
- ; DEY
- op88:
- subq.b #1,drY
- move.b drY,drST
- ext.w drST
- DISPATCH
-
- op89:
- UNUSED
-
- ; TXA
- op8A:
- move.b drX,drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- op8B:
- UNUSED
-
- ; STY abs
- op8C:
- EA_abs
- WriteYService
- move.b drY,(arEA)
- DISPATCH
-
- ; STA abs
- op8D:
- EA_abs
- WriteAService
- move.b drA,(arEA)
- DISPATCH
-
- ; STX abs
- op8E:
- EA_abs
- WriteXService
- move.b drX,(arEA)
- DISPATCH
-
- op8F:
- UNUSED
-
- ; BCC
- op90:
- move.b (arPC)+,drDATA
- tst.b drC
- bne.s nobcc
- ext.w drDATA
- adda.w drDATA,arPC
- nobcc:
- DISPATCH
-
- ; STA (zp),Y
- op91:
- EA_zpYind
- WriteAService
- move.b drA,(arEA)
- DISPATCH
-
- op92:
- UNUSED
- op93:
- UNUSED
-
- ; STY zp,X
- op94:
- EA_zpX
- move.b drY,(arEA)
- DISPATCH
-
- ; STA zp,X
- op95:
- EA_zpX
- move.b drA,(arEA)
- DISPATCH
-
- ; STX zp,Y
- op96:
- EA_zpY
- move.b drX,(arEA)
- DISPATCH
-
- op97:
- UNUSED
-
- ; TYA
- op98:
- move.b drY,drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; STA abs,Y
- op99:
- EA_absY
- WriteAService
- move.b drA,(arEA)
- DISPATCH
-
- ; TXS
- op9A:
- move.b drX,drSP
- DISPATCH
-
- op9B:
- UNUSED
- op9C:
- UNUSED
-
- ; STA abs,X
- op9D:
- EA_absX
- WriteAService
- move.b drA,(arEA)
- DISPATCH
-
- op9E:
- UNUSED
- op9F:
- UNUSED
-
- ; LDY #
- opA0:
- move.b (arPC)+,drY
- move.b drY,drST
- ext.w drST
- DISPATCH
-
- ; LDA (zp,X)
- opA1:
- EA_zpXind
- ReadService
- move.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; LDX #
- opA2:
- move.b (arPC)+,drX
- move.b drX,drST
- ext.w drST
- DISPATCH
-
- opA3:
- UNUSED
-
- ; LDY zp
- opA4:
- EA_zp
- move.b (arEA),drY
- move.b drY,drST
- ext.w drST
- DISPATCH
-
- ; LDA zp
- opA5:
- EA_zp
- move.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; LDX zp
- opA6:
- EA_zp
- move.b (arEA),drX
- move.b drX,drST
- ext.w drST
- DISPATCH
-
- opA7:
- UNUSED
-
- ; TAY
- opA8:
- move.b drA,drY
- move.b drY,drST
- ext.w drST
- DISPATCH
-
- ; LDA #
- opA9:
- move.b (arPC)+,drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; TAX
- opAA:
- move.b drA,drX
- move.b drX,drST
- ext.w drST
- DISPATCH
-
- opAB:
- UNUSED
-
- ; LDY abs
- opAC:
- EA_abs
- ReadService
- move.b (arEA),drY
- move.b drY,drST
- ext.w drST
- DISPATCH
-
- ; LDA abs
- opAD:
- EA_abs
- ReadService
- move.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; LDX abs
- opAE:
- EA_abs
- ReadService
- move.b (arEA),drX
- move.b drX,drST
- ext.w drST
- DISPATCH
-
- opAF:
- UNUSED
-
- ; BCS
- opB0:
- move.b (arPC)+,drDATA
- tst.b drC
- beq.s nobcs
- ext.w drDATA
- adda.w drDATA,arPC
- nobcs:
- DISPATCH
-
- ; LDA (zp),Y
- opB1:
- EA_zpYind
- ReadService
- move.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- opB2:
- UNUSED
- opB3:
- UNUSED
-
- ; LDY zp,X
- opB4:
- EA_zpX
- move.b (arEA),drY
- move.b drY,drST
- ext.w drST
- DISPATCH
-
- ; LDA zp,X
- opB5:
- EA_zpX
- move.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; LDX zp,Y
- opB6:
- EA_zpY
- move.b (arEA),drX
- move.b drX,drST
- ext.w drST
- DISPATCH
-
- opB7:
- UNUSED
-
- ; CLV
- opB8:
- clr.b bV(arEMUL)
- DISPATCH
-
- ; LDA abs,Y
- opB9:
- EA_absY
- ReadService
- move.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; TAX
- opBA:
- move.b drSP,drX
- move.b drX,drST
- ext.w drST
- DISPATCH
-
- opBB:
- UNUSED
-
- ; LDY abs,X
- opBC:
- EA_absX
- ReadService
- move.b (arEA),drY
- move.b drY,drST
- ext.w drST
- DISPATCH
-
- ; LDA abs,X
- opBD:
- EA_absX
- ReadService
- move.b (arEA),drA
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; LDX abs,Y
- opBE:
- EA_absY
- ReadService
- move.b (arEA),drX
- move.b drX,drST
- ext.w drST
- DISPATCH
-
- opBF:
- UNUSED
-
- ; CPY #
- opC0:
- move.b (arPC)+,drDATA
- move.w drY,drEA
- sub.b drDATA,drEA
- scc drC
- move.b drEA,drST
- ext.w drST
- DISPATCH
-
- ; CMP (zp,X)
- opC1:
- EA_zpXind
- ReadService
- move.b (arEA),drDATA
- move.w drA,drST ; must do a subtract without affecting arA
- sub.b drDATA,drST
- scc drC
- ext.w drST
- DISPATCH
-
- opC2:
- UNUSED
- opC3:
- UNUSED
-
- ; CPY zp
- opC4:
- EA_zp
- move.b (arEA),drDATA
- move.w drY,drEA
- sub.b drDATA,drEA
- scc drC
- move.b drEA,drST
- ext.w drST
- DISPATCH
-
- ; CMP zp
- opC5:
- EA_zp
- move.b (arEA),drDATA
- move.w drA,drST ; must do a subtract without affecting arA
- sub.b drDATA,drST
- scc drC
- ext.w drST
- DISPATCH
-
- ; DEC zp
- opC6:
- EA_zp
- subq.b #1,(arEA)
- move.b (arEA),drST
- ext.w drST
- DISPATCH
-
- opC7:
- UNUSED
-
- ; INY
- opC8:
- addq.b #1,drY
- move.b drY,drST
- ext.w drST
- DISPATCH
-
- ; CMP #
- opC9:
- move.b (arPC)+,drDATA
- move.w drA,drST ; must do a subtract without affecting arA
- sub.b drDATA,drST
- scc drC
- ext.w drST
- DISPATCH
-
- ; DEX
- opCA:
- subq.b #1,drX
- move.b drX,drST
- ext.w drST
- DISPATCH
-
- opCB:
- UNUSED
-
- ; CPY abs
- opCC:
- EA_abs
- ReadService
- move.b (arEA),drDATA
- move.w drY,drEA
- sub.b drDATA,drEA
- scc drC
- move.b drEA,drST
- ext.w drST
- DISPATCH
-
- ; CMP abs
- opCD:
- EA_abs
- ReadService
- move.b (arEA),drDATA
- move.w drA,drST ; must do a subtract without affecting arA
- sub.b drDATA,drST
- scc drC
- ext.w drST
- DISPATCH
-
- ; DEC abs
- opCE:
- EA_abs
- ReadService
- move.b (arEA),drST
- subq.b #1,drST
- ext.w drST
- WriteService
- move.b drST,(arEA)
- DISPATCH
-
- opCF:
- UNUSED
-
- ; BNE
- opD0:
- move.b (arPC)+,drDATA
- tst.b drST
- beq.s nobne
- ext.w drDATA
- adda.w drDATA,arPC
- nobne:
- DISPATCH
-
- ; CMP (zp),Y
- opD1:
- EA_zpYind
- ReadService
- move.b (arEA),drDATA
- move.w drA,drST ; must do a subtract without affecting arA
- sub.b drDATA,drST
- scc drC
- ext.w drST
- DISPATCH
-
- opD2:
- UNUSED
- opD3:
- UNUSED
- opD4:
- UNUSED
-
- ; CMP zp,X
- opD5:
- EA_zpX
- move.b (arEA),drDATA
- move.w drA,drST ; must do a subtract without affecting arA
- sub.b drDATA,drST
- scc drC
- ext.w drST
- DISPATCH
-
- ; DEC zp,X
- opD6:
- EA_zpX
- subq.b #1,(arEA)
- move.b (arEA),drST
- ext.w drST
- DISPATCH
-
- opD7:
- UNUSED
-
- ; CLD
- opD8:
- bclr #31,drST
- ; sf bD(arEMUL)
- DISPATCH
-
- ; CMP abs,Y
- opD9:
- EA_absY
- ReadService
- move.b (arEA),drDATA
- move.w drA,drST ; must do a subtract without affecting arA
- sub.b drDATA,drST
- scc drC
- ext.w drST
- DISPATCH
-
- opDA:
- UNUSED
- opDB:
- UNUSED
- opDC:
- UNUSED
-
- ; CMP abs,X
- opDD:
- EA_absX
- ReadService
- move.b (arEA),drDATA
- move.w drA,drST ; must do a subtract without affecting arA
- sub.b drDATA,drST
- scc drC
- ext.w drST
- DISPATCH
-
- ; DEC abs,X
- opDE:
- EA_absX
- ReadService
- move.b (arEA),drST
- subq.b #1,drST
- ext.w drST
- WriteService
- move.b drST,(arEA)
- DISPATCH
-
- opDF:
- UNUSED
-
- ; CPX #
- opE0:
- move.b (arPC)+,drDATA
- move.w drX,drEA
- sub.b drDATA,drEA
- scc drC
- move.b drEA,drST
- ext.w drST
- DISPATCH
-
- ; SBC (zp,X)
- opE1:
- EA_zpXind
- ReadService
- tst.l drST ; test D flag
- ; tst.b bD(arEMUL)
- bmi.s opE1dec
- move.b (arEA),drDATA
- not.b drC
- add.b drC,drC
- subx.b drDATA,drA
- scc drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
- opE1dec:
- move.b (arEA),drDATA
- not.b drC
- add.b drC,drC ; set X flag
- clr.b drC ; sets Z flag for the SBCD without clearing X
- sbcd drDATA,drA
- scc drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- opE2:
- UNUSED
- opE3:
- UNUSED
-
- ; CPX zp
- opE4:
- EA_zp
- move.b (arEA),drDATA
- move.w drX,drEA
- sub.b drDATA,drEA
- scc drC
- move.b drEA,drST
- ext.w drST
- DISPATCH
-
- ; SBC zp
- opE5:
- EA_zp
- tst.l drST ; test D flag
- ; tst.b bD(arEMUL)
- bmi.s opE5dec
- move.b (arEA),drDATA
- not.b drC
- add.b drC,drC
- subx.b drDATA,drA
- scc drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
- opE5dec:
- move.b (arEA),drDATA
- not.b drC
- add.b drC,drC ; set X flag
- clr.b drC ; sets Z flag for the SBCD without clearing X
- sbcd drDATA,drA
- scc drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; INC zp
- opE6:
- EA_zp
- addq.b #1,(arEA)
- move.b (arEA),drST
- ext.w drST
- DISPATCH
-
- opE7:
- UNUSED
-
- ; INX
- opE8:
- addq.b #1,drX
- move.b drX,drST
- ext.w drST
- DISPATCH
-
- ; SBC #
- opE9:
- tst.l drST ; test D flag
- ; tst.b bD(arEMUL)
- bmi.s opE9dec
- move.b (arPC)+,drDATA
- not drC
- add.b drC,drC
- subx.b drDATA,drA
- scc drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
- opE9dec:
- move.b (arPC)+,drDATA
- not.b drC
- add.b drC,drC ; set X flag
- clr.b drC ; sets Z flag for the SBCD without clearing X
- sbcd drDATA,drA
- scc drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; NOP
- opEA:
- DISPATCH
- opEB:
- UNUSED
-
- ; CPX abs
- opEC:
- EA_abs
- ReadService
- move.b (arEA),drDATA
- move.w drX,drEA
- sub.b drDATA,drEA
- scc drC
- move.b drEA,drST
- ext.w drST
- DISPATCH
-
- ; SBC abs
- opED:
- EA_abs
- ReadService
- tst.l drST ; test D flag
- ; tst.b bD(arEMUL)
- bmi.s opEDdec
- move.b (arEA),drDATA
- not.b drC
- add.b drC,drC
- subx.b drDATA,drA
- scc drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
- opEDdec:
- move.b (arEA),drDATA
- not.b drC
- add.b drC,drC ; set X flag
- clr.b drC ; sets Z flag for the SBCD without clearing X
- sbcd drDATA,drA
- scc drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; INC abs
- opEE:
- EA_abs
- ReadService
- move.b (arEA),drST
- addq.b #1,drST
- ext.w drST
- WriteService
- move.b drST,(arEA)
- DISPATCH
-
- opEF:
- UNUSED
-
- ; BEQ
- opF0:
- move.b (arPC)+,drDATA ; get relative offset
- tst.b drST
- bne.s nobeq
- ext.w drDATA
- adda.w drDATA,arPC
- nobeq:
- DISPATCH
-
- ; SBC (zp),Y
- opF1:
- EA_zpYind
- ReadService
- tst.l drST ; test D flag
- ; tst.b bD(arEMUL)
- bmi.s opF1dec
- move.b (arEA),drDATA
- not.b drC
- add.b drC,drC
- subx.b drDATA,drA
- scc drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
- opF1dec:
- move.b (arEA),drDATA
- not.b drC
- add.b drC,drC ; set X flag
- clr.b drC ; sets Z flag for the SBCD without clearing X
- sbcd drDATA,drA
- scc drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- opF2:
- UNUSED
- opF3:
- UNUSED
- opF4:
- UNUSED
-
- ; SBC zp,X
- opF5:
- EA_zpX
- tst.l drST ; test D flag
- ; tst.b bD(arEMUL)
- bmi.s opF5dec
- move.b (arEA),drDATA
- not.b drC
- add.b drC,drC
- subx.b drDATA,drA
- scc drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
- opF5dec:
- move.b (arEA),drDATA
- not.b drC
- add.b drC,drC ; set X flag
- clr.b drC ; sets Z flag for the SBCD without clearing X
- sbcd drDATA,drA
- scc drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; INC zp,X
- opF6:
- EA_zpX
- addq.b #1,(arEA)
- move.b (arEA),drST
- ext.w drST
- DISPATCH
-
- opF7:
- UNUSED
-
- ; SED
- opF8:
- bset #31,drST
- ; st bD(arEMUL)
- DISPATCH
-
- ; SBC abs,Y
- opF9:
- EA_absY
- ReadService
- tst.l drST ; test D flag
- ; tst.b bD(arEMUL)
- bmi.s opF9dec
- move.b (arEA),drDATA
- not.b drC
- add.b drC,drC
- subx.b drDATA,drA
- scc drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
- opF9dec:
- move.b (arEA),drDATA
- not.b drC
- add.b drC,drC ; set X flag
- clr.b drC ; sets Z flag for the SBCD without clearing X
- sbcd drDATA,drA
- scc drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- opFA:
- UNUSED
- opFB:
- UNUSED
- opFC:
- UNUSED
-
- ; SBC abs,X
- opFD:
- EA_absX
- ReadService
- tst.l drST ; test D flag
- ; tst.b bD(arEMUL)
- bmi.s opFDdec
- move.b (arEA),drDATA
- not.b drC
- add.b drC,drC
- subx.b drDATA,drA
- scc drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
- opFDdec:
- move.b (arEA),drDATA
- not.b drC
- add.b drC,drC ; set X flag
- clr.b drC ; sets Z flag for the SBCD without clearing X
- sbcd drDATA,drA
- scc drC
- svs bV(arEMUL)
- move.b drA,drST
- ext.w drST
- DISPATCH
-
- ; INC abs,X
- opFE:
- EA_absX
- ReadService
- move.b (arEA),drST
- addq.b #1,drST
- ext.w drST
- WriteService
- move.b drST,(arEA)
- DISPATCH
-
- opFF:
- UNUSED
-
- opXX:
- UNUSED
- }
- }
-
- /************************************************************************
-
- 6502 Monitor subroutines, kept here for uP independence
-
- ************************************************************************/
-
- int Peek(uAddr)
- unsigned uAddr;
- {
- return ((int) *(char *)(lMemory + (long)uAddr)) & 0xFF;
- }
-
- int Dpeek(uAddr)
- unsigned uAddr;
- {
- return (unsigned)(Peek(uAddr)) + (unsigned)(Peek(uAddr+1)<<8);
- }
-
- void Poke(uAddr, b)
- unsigned uAddr;
- int b;
- {
- *(char *)(lMemory + (long)uAddr) = (char)b;
- }
-
- int GetReg(chReg)
- int chReg;
- {
- switch (chReg)
- {
- default:
- Assert(FALSE, "GetReg(): invalid reg");
- return;
- case 'A':
- return *(char *)(lEmul + (bRegA));
- case 'X':
- return *(char *)(lEmul + (bRegX));
- case 'Y':
- return *(char *)(lEmul + (bRegY));
- case 'P':
- return *(char *)(lEmul + (bRegP));
- case 'SP':
- return *(int *)(lEmul + (wRegSP));
- case 'PC':
- return *(int *)(lEmul + (wRegPC));
- }
- }
-
- void PutReg(chReg, w)
- int chReg;
- int w;
- {
- switch (chReg)
- {
- default:
- Assert(FALSE, "PutReg(): invalid reg");
- return;
- case 'A':
- *(char *)(lEmul + (bRegA)) = (char)w;
- case 'X':
- *(char *)(lEmul + (bRegX)) = (char)w;
- case 'Y':
- *(char *)(lEmul + (bRegY)) = (char)w;
- case 'P':
- *(char *)(lEmul + (bRegP)) = (char)w;
- case 'SP':
- *(int *)(lEmul + (wRegSP)) = (char)w;
- case 'PC':
- *(int *)(lEmul + (wRegPC)) = w;
- }
- }
-
- int CchShowRegs(pch)
- char *pch;
- {
- int regP;
- char chNil = '.';
-
- Blit("PC: A: X: Y: SP: P: ", pch);
-
- XtoPch(pch+3, GetReg('PC'));
- BtoPch(pch+10, GetReg('A'));
- BtoPch(pch+15, GetReg('X'));
- BtoPch(pch+20, GetReg('Y'));
- BtoPch(pch+26, GetReg('SP'));
- BtoPch(pch+31, regP = GetReg('P'));
- pch[34] = (regP & NBIT) ? 'N' : chNil;
- pch[35] = (regP & VBIT) ? 'V' : chNil;
- pch[36] = '_';
- pch[37] = (regP & BBIT) ? 'B' : chNil;
- pch[38] = (regP & DBIT) ? 'D' : chNil;
- pch[39] = (regP & IBIT) ? 'I' : chNil;
- pch[40] = (regP & ZBIT) ? 'Z' : chNil;
- pch[41] = (regP & CBIT) ? 'C' : chNil;
-
- return 42;
- }
-
- /* start execution at address uAddr */
- int RunAt(puAddr)
- unsigned int *puAddr;
- {
- unsigned int uAddr = *puAddr;
-
- #ifdef NDEBUG
- printf("executing at: %4x\n", uAddr);
- printf("fTrace = %d\n", fTrace);
- #endif
-
- PutReg('PC',uAddr);
- Supexec(execute);
- *puAddr = GetReg('PC');
-
- #ifdef NDEBUG
- printf("exit code: %d\n", *(int *)(lEmul + (wExitCode)));
- #endif
- return *(int *)(lEmul + (wExitCode));
- }
-
- /* start execution at the address stored in the vector at uAddr */
- int RunThru(puAddr)
- unsigned int *puAddr;
- {
- unsigned int uAddr = *puAddr;
-
- *puAddr = (unsigned)(Peek(uAddr)) + (unsigned)(Peek(uAddr+1)<<8);
- return (RunAt(puAddr));
- }
-
- /* Disassemble instruction at location uMem to space filled buffer pch. */
- /* Returns with puMem incremented appropriate number of bytes. */
-
- int CchDisAsm(pch, puMem)
- register char *pch;
- register unsigned int *puMem;
- {
- register unsigned char bOpcode;
- register long lPackedOp;
- char *pch0 = pch;
- register int md;
-
- *pch++ = ',';
- XtoPch(pch, *puMem) + 1;
- pch += 5;
-
- /* get opcode */
- bOpcode = Peek(*puMem);
- BtoPch(pch, bOpcode);
-
- /* get packed opcode mnemonic and addressing mode */
- lPackedOp = rglMnemonics[bOpcode] ;
-
- /* addressing mode is LSB of long */
- md = (int)(lPackedOp & 0x0FL);
-
- /* first hex dump the bytes of the instruction */
- switch (md)
- {
- /* 2 operands */
- case 0x07:
- case 0x08:
- case 0x09:
- case 0x0C:
- BtoPch(pch + 6, Peek(*puMem + 2));
-
- /* one operand */
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x04:
- case 0x05:
- case 0x06:
- case 0x0B:
- BtoPch(pch + 3, Peek(*puMem + 1));
-
- /* no operands */
- case 0x00:
- case 0x0A:
- pch += 10;
- break;
- }
-
- /* now dump the mnemonic */
- asm
- {
- move.b #' ',lPackedOp ; clear the addressing mode byte
- }
- Assert(((long)pch & 1L) == 0L, "dump mnemonic at odd address!!");
- *(long *)pch = lPackedOp;
- pch += 4;
-
- *puMem += 1;
-
- switch (md)
- {
- case 0x00:
- break;
-
- case 0x01:
- pch = Blit("#$", pch);
- BtoPch(pch, Peek(*puMem));
- pch += 2;
- *puMem += 1;
- break;
-
- case 0x02:
- *pch++ = '$';
- BtoPch(pch, Peek(*puMem));
- pch += 2;
- *puMem += 1;
- break;
-
- case 0x03:
- *pch++ = '$';
- BtoPch(pch, Peek(*puMem));
- pch += 2;
- pch = Blit(",X",pch);
- *puMem += 1;
- break;
-
- case 0x04:
- *pch++ = '$';
- BtoPch(pch, Peek(*puMem));
- pch += 2;
- pch = Blit(",Y",pch);
- *puMem += 1;
- break;
-
- case 0x05:
- pch = Blit("($", pch);
- BtoPch(pch, Peek(*puMem));
- pch += 2;
- pch = Blit(",X)", pch);
- *puMem += 1;
- break;
-
- case 0x06:
- pch = Blit("($", pch);
- BtoPch(pch, Peek(*puMem));
- pch += 2;
- pch = Blit("),Y", pch);
- *puMem += 1;
- break;
-
- case 0x07:
- *pch++ = '$';
- BtoPch(pch, Peek(*puMem + 1));
- pch += 2;
- BtoPch(pch, Peek(*puMem));
- pch += 2;
- *puMem += 2;
- break;
-
- case 0x08:
- *pch++ = '$';
- BtoPch(pch, Peek(*puMem + 1));
- pch += 2;
- BtoPch(pch, Peek(*puMem));
- pch += 2;
- *puMem += 2;
- pch = Blit(",X", pch);
- break;
-
- case 0x09:
- *pch++ = '$';
- BtoPch(pch, Peek(*puMem + 1));
- pch += 2;
- BtoPch(pch, Peek(*puMem));
- pch += 2;
- *puMem += 2;
- pch = Blit(",Y", pch);
- break;
-
- case 0x0A:
- *pch++ = 'A';
- break;
-
- case 0x0B:
- {
- unsigned uMem;
-
- *pch++ = '$';
- uMem = (*puMem + 1 + (int)((char)Peek(*puMem)));
- BtoPch(pch, uMem>>8);
- pch += 2;
- BtoPch(pch, (char)uMem);
- pch += 2;
- *puMem += 1;
- }
- break;
-
- case 0x0C:
- pch = Blit("($", pch);
- BtoPch(pch, Peek(*puMem + 1));
- pch += 2;
- BtoPch(pch, Peek(*puMem));
- pch += 2;
- *pch++ = ')';
- *puMem += 2;
- break;
- }
-
- return (int)(pch - pch0);
- }
-
-
- /***********************************************************************/
-
- fn_nul()
- {
- }
-
- int (*pHookIn)()=fn_nul, (*pUnHook)()=fn_nul;
- long *qlVBIslot;
-
- VBI_on(qbVBI)
- long qbVBI;
- {
- #ifdef NDEBUG
- printf("VBI_on(): qbVBI = $%5lx\n", qbVBI);
- #endif
-
- qlVBIslot = *(long **)0x456L;
-
- #ifdef NDEBUG
- printf("VBI_on(): #1 qlVBIslot = $%5lx\n", qlVBIslot);
- #endif
-
- while (*qlVBIslot != 0L)
- {
- qlVBIslot++;
- #ifdef NDEBUG
- printf("VBI_on(): #2 qlVBIslot = $%5lx\n", qlVBIslot);
- #endif
- }
-
- *qlVBIslot = qbVBI;
-
- Vsync();
-
- #ifdef NDEBUG
- printf("VBI_on(): qlVBIslot = $%5lx\n", qlVBIslot);
- #endif
- }
-
- VBI_off()
- {
- *qlVBIslot = 0L;
- Vsync();
-
- #ifdef NDEBUG
- printf("VBI_off(): qlVBIslot = $%5lx\n", qlVBIslot);
- #endif
- }
-
- /***********************************************************************/
-
-
-